/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *   gbx-emu - gameboy.h                                                   *
 *   gbx-emu homepage: http://code.google.com/p/gbx-emu/                   *
 *   Copyright (C) 2009 olejl77@gmail.com                                  *
 *                                                                         *
 *   This program is free software: you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation, either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the          *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef GAMEBOY_H
#define GAMEBOY_H

#include <QThread>
#include <QImage>
#include <QSize>
#include "common.h"
#include "debugger.h"

typedef struct
{
    u8 name[0x0f];      // 0x0134
    u8 gb_type;         // 0x0143
    u16 license_code;   // 0x0144
    u8 indicator;       // 0x0146
    u8 cart_type;       // 0x0147
    u8 rom_size;        // 0x0148
    u8 ram_size;        // 0x0149
    u8 destination_code;// 0x014a
    u8 license_code_old;// 0x014b
    u8 rom_version_mask;// 0x014c
    u8 complement_check;// 0x014d
    u16 checksum;       // 0x014e
} ROM_HEADER;

class Memory;
class Cpu;
class Screen;
class Debugger;
class MainWindow;
class Log;
class Gameboy : public QThread, public Common
{
    Q_OBJECT

friend class Cpu;
friend class Memory;
private:
    bool loadRom(QString fileName);

    MainWindow *_ui;
    Memory *_mem;
    Cpu *_cpu;
    Screen *_scr;
    Debugger *_dbg;
    Log *_log;

    u8 *_cart;
    s32 _cartSize;
    ROM_HEADER _rom_header;
    QSize _resultSize;
    QImage *_image;

    bool _quit;
    bool _frameLimiterEnabled;

public:
    Gameboy(QObject *parent = 0);
    ~Gameboy();

    void stopEmu() { _quit = true; }
    u8* getCart() { return _cart; }
    u32 getCartSize() { return _cartSize; }
    void enableFrameLimiter(bool enabled) { _frameLimiterEnabled = enabled; }
    void milliSleep(u32 millisec) { msleep(millisec); }
    bool powerOn(QSize resultSize, QString fileName);
    void init(MainWindow *ptr, Log *ptr_2);

signals:
    void updateScreen(const QImage &image);
    void newFps(double fps);
    void updatePC(unsigned short pc);

protected:
    void run();

private:
};

enum { HEADER_START = 0x0134};
enum { HEADER_SIZE = 0x1c};

enum {
    S_256Kbit = 0x00, //= 32KByte = 2 banks
    S_512Kbit = 0x01, //= 64KByte = 4 banks
    S_1Mbit =   0x02, //= 128KByte = 8 banks
    S_2Mbit =   0x03, //= 256KByte = 16 banks
    S_4Mbit =   0x04, //= 512KByte = 32 banks
    S_8Mbit =   0x05, //= 1MByte = 64 banks
    S_16Mbit =  0x06, //= 2MByte = 128 banks
    //9Mbit     $52,  //= 1.1MByte = 72 banks
    //10Mbit    $53,  //= 1.2MByte = 80 banks
    //12Mbit    $54,  //= 1.5MByte = 96 banks
};

enum RamSize{
    NONE,       //- None
    S_16kBit,   //= 2kB  =  1 bank
    S_64kBit,   //= 8kB  =  1 bank
    S_256kBit,  //= 32kB =  4 banks
    S_1MBit,    //=128kB = 16 banks
};

enum {Japanese, Non_Japanese};

enum LicenseeCode{
    Check    = 0x33, // 0144/0145 for Licensee code.
    Accolade = 0x79,
    Konami   = 0xa4
    // (Super GameBoy function won't work if <> $33.)
};

#endif // GAMEBOY_H

